package com.uyayo.core.resolver;

import com.uyayo.framework.common.util.CodeUtil;
import com.uyayo.framework.common.util.thread.Pool;
import com.uyayo.framework.common.util.thread.Task;
import com.uyayo.framework.common.util.thread.ThreadPool;
import com.uyayo.system.monitor.entity.SysException;
import com.uyayo.system.monitor.service.ExceptionsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.util.Date;

/**
 * 
 * 全局异常处理器
 * @author	胡逢君
 * @date	2016-9-20上午11:57:09
 * @version 1.0
 */
public class CustomExceptionResolver implements HandlerExceptionResolver {

	@Autowired
	private ExceptionsService exceptionsService;

	@Autowired
	private  MessageSource messageSource;

	private Class<?>[] excludedExceptions;

	/**
	 * Set one or more exceptions to be excluded from the exception mappings.
	 * Excluded exceptions are checked first and if one of them equals the actual
	 * exception, the exception will remain unresolved.
	 * @param excludedExceptions one or more excluded exception types
	 */
	public void setExcludedExceptions(Class<?>... excludedExceptions) {
		this.excludedExceptions = excludedExceptions;
	}
	
	/**
	 * （非 Javadoc）
	 * @param request
	 * @param response
	 * @param handler
	 * @param ex 系统 抛出的异常
	 * @return
	 * @see HandlerExceptionResolver#resolveException(HttpServletRequest, HttpServletResponse, Object, Exception)
	 */
	@Override
	public ModelAndView resolveException(HttpServletRequest request,
			HttpServletResponse response, Object handler, Exception ex) {
		//handler就是处理器适配器要执行Handler对象（只有method）
		
		//过滤异常类
		if (this.excludedExceptions != null) {
			for (Class<?> excludedEx : this.excludedExceptions) {
				if (excludedEx.equals(ex.getClass())) {
					return null;
				}
			}
		}
		
		//错误信息
		ModelAndView modelAndView = new ModelAndView();
		String message = messageSource.getMessage("server.error.500",new Object[]{}, request.getLocale());
		//将错误信息传到页面
		modelAndView.addObject("message", message);
		
		//指向错误页面
		modelAndView.setViewName("error/500");
		
		saveException(request,response, handler, ex);
		
		return modelAndView;
	}

	private void saveException(final HttpServletRequest request,
			HttpServletResponse response, final Object handler, final Exception ex) {
		Pool pool = ThreadPool.getInstance();
		Task etask = new Task(CodeUtil.getTimeSequenceAsRandom(), "保存系统事件中") {
			@Override
			public void execute() {

				String exceptionId = CodeUtil.getTimeSequenceAsRandom();
				StackTraceElement[] st = ex.getStackTrace();
				String message = ex.getMessage();
				if(message!=null){
					message = message.replaceAll("\\$", "");
				}
			    String clazz;
			    StackTraceElement[] arrayOfStackTraceElement;
			    StackTraceElement stackTraceElement;
			    if ((arrayOfStackTraceElement = st).length != 0) { 
			    	stackTraceElement = arrayOfStackTraceElement[0];
			    	clazz = stackTraceElement.getClassName();
				    HandlerMethod handlerMethod = (HandlerMethod) handler;
			        Method method = handlerMethod.getMethod();
				    SysException exceptions = new SysException();
				    exceptions.setId(exceptionId);
				    exceptions.setClazz(clazz);
				    exceptions.setCreatedTime(new Date());
				    exceptions.setMethodName(stackTraceElement.getMethodName());
				    exceptions.setDescription(message);
				    exceptions.setRemark(method.toString());
				    try {
						exceptionsService.saveSysException(exceptions);
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
			}
		};
		pool.execute(etask);
	}

}
